﻿using System;
using System.Collections;
using System.Collections.Generic;

namespace IceDog.Lib.Farm.Generic
{
    public class Farm<T> : IEnumerable<T> where T : Animal
    {
        private List<T> animalList = new List<T>();

        public List<T> AnimalList
        {
            get
            {
                return animalList;
            }
        }

        public IEnumerator<T> GetEnumerator()
        {
            return animalList.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return animalList.GetEnumerator();
        }

        public void MakeNoise()
        {
            animalList.ForEach(x => x.MakeNoise());
        }

        public void FeedAllAnimal()
        {
            animalList.ForEach(x => x.Feed());
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public Farm<Cow> GetCowList()
        {
            var farm = new Farm<Cow>();
            foreach (T item in AnimalList)
            {
                if (item is Cow)
                {
                    farm.AnimalList.Add(item as Cow);
                }
            }
            return farm;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="U"></typeparam>
        /// <returns></returns>
        public Farm<U> GetSubList<U>() where U : T
        {
            var farm = new Farm<U>();
            foreach (T item in AnimalList)
            {
                if (item is U)
                {
                    farm.AnimalList.Add(item as U);
                }
            }
            return farm;
        }
        /// <summary>
        /// 隐式转换
        /// </summary>
        /// <param name="farm"></param>
        public static implicit operator List<Animal>(Farm<T> farm)
        {
            var res = new List<Animal>();
            foreach (T t in farm)
            {
                res.Add(t);
            }
            return res;
        }
        /// <summary>
        /// 显示转换
        /// </summary>
        /// <param name="list"></param>
        public static explicit operator Farm<T>(List<Animal> list)
        {
            var farm = new Farm<T>();
            foreach (Animal a in list)
            {
                var b = a as T;
                if (b != null)
                {
                    farm.AnimalList.Add(b);
                }
                else
                {
                    throw new ArgumentException("强制转换失败", "list");
                }
            }
            return farm;
        }

        public static Farm<T> operator +(Farm<T> farm1, List<T> farm2)
        {
            var res = new Farm<T>();
            res.AnimalList.AddRange(farm1);
            foreach (T animal in farm2)
            {
                if (!res.AnimalList.Contains(animal))
                {
                    res.AnimalList.Add(animal);
                }
            }
            return res;
        }
        public static Farm<T> operator +(List<T> farm1, Farm<T> farm2)
        {
            return farm2 + farm1;
        }
        /// <summary>
        /// 隐式转换
        /// </summary>
        /// <param name="farm"></param>
        public static implicit operator Farm<Animal>(Farm<T> farm)
        {
            var res = new Farm<Animal>();
            foreach (T t in farm)
            {
                res.AnimalList.Add(t);
            }
            return res;
        }
        public static Farm<T> operator +(Farm<T> farm1, Farm<T> farm2)
        {
            var res = new Farm<T>();
            res.AnimalList.AddRange(farm1);
            foreach (T animal in farm2)
            {
                if (!res.AnimalList.Contains(animal))
                {
                    res.AnimalList.Add(animal);
                }
            }
            return res;
        }
    }
}
